<?php

defined('SYSPATH') or die('No direct access allowed.');

/**
 * Repository of User
 */
class Model_User extends Model_Generic implements Model_Interface {

    protected $_table_name = 'users';
    protected $_model = 'User';
    protected $_o_entity;
    private static $_inst = null;
    //protected $_db_group = '';

    protected $_has_many = array(
        'usergroup' => array(
            'model' => 'User_Group',
            'foreign_key' => 'user_id'
        ),
        'group' => array(
            'model' => 'Group',
            'through' => 'user_groups', // table name
            'foreign_key' => 'user_id', // foreign_key of this object in middle table(ex: customer_contents)
            'far_key' => 'group_id'  // foreign_key of content table in middle table(ex: customer_contents)
        ),
        'userpermission' => array(
            'model' => 'User_Permission',
            'foreign_key' => 'user_id'
        ),
        'permission' => array(
            'model' => 'Permission',
            'through' => 'user_permissions', // table name
            'foreign_key' => 'user_id', // foreign_key of this object in middle table(ex: customer_contents)
            'far_key' => 'permission_id'  // foreign_key of content table in middle table(ex: customer_contents)
        ),
    );

    protected $_has_one = array(
        'sessionuser' => array(
            'model' => 'Session_User',
        )
    );
    /**
     * Call this method to get singleton
     *
     * @return Model_User
     */
    public static function get_instance()
    {
        if (self::$_inst === null)
        {
            self::$_inst = new Model_User;
        }
        return self::$_inst;
    }

    public function __construct($id = NULL)
    {
        $this->_o_entity = new Domain_Entities_User;
        $this->_table_columns = $this->_o_entity->to_column_array();
        parent::__construct($id);
    }

    /**
     *
     * @param Domain_Entities_User $o_entity
     * @return <type>
     */
    public function insert_by($o_entity)
    {
        try {
            return $this->insert_object($this, $o_entity, $this->_model);
        } catch (Exception $e) {
            Log::instance()->add(Log::ERROR, 'insert_by($o_entity): ' . $e);
            Log::instance()->write();
            return null;
        }
    }

    /**
     *
     * @param Domain_Entities_User $o_entity
     * @return <type> 
     */
    public function update_by($o_entity)
    {
        try {
            return $this->update_object($this, $o_entity, $this->_model);
        } catch (Exception $e) {
            Log::instance()->add(Log::ERROR, 'update_by($o_entity): ' . $e);
            Log::instance()->write();
            return null;
        }
    }

    /**
     *
     * @param <type> $id
     * @return <type> 
     */
    public function delete_by($id)
    {
        try {
            return $this->delete_object($this, $id, 1);
        } catch (Exception $e) {
            Log::instance()->add(Log::ERROR, 'update_by($o_entity): ' . $e);
            Log::instance()->write();
            return false;
        }
    }

    /**
     *
     * @param <type> $id
     */
    public function load($id)
    {
        try {
            $this->_db = Database::instance('master');
            $this->clear();
            $this->set_column();
            $this->select();
            $this->where('id', '=', $id);
            return $this->find();
        } catch (Exception $e) {
            Log::instance()->add(Log::ERROR, 'load($id): ' . $e);
            Log::instance()->write();
            return null;
        }
    }

    /**
     * @return Domain_Entities_User
     */
    public function get_data()
    {
        try {
            $this->_o_entity = new Domain_Entities_User;
            return $this->get_data_object($this);
        } catch (Exception $e) {
            Log::instance()->add(Log::ERROR, 'get_data(): ' . $e);
            Log::instance()->write();
            return null;
        }
    }

    /**
     *
     * @param <type> $s_column is mane of column in db
     * @param <type> $a_option is array( where,order by, group by, limit, offset )
     * @param <type> $val
     */
    public function builder_select($s_column, $a_option, $val = null)
    {
        try {
            return $this->builder_select_object($this, $s_column, $a_option, $val);
        } catch (Exception $e) {
            Log::instance()->add(Log::ERROR, 'builder_select($s_column, $a_option, $val = null): ' . $e);
            Log::instance()->write();
            return null;
        }
    }

    /**
     *
     * @param <type> $a_columns
     */
    public function set_column($a_columns = array())
    {
        try {
            $this->set_column_object($this, $a_columns);
        } catch (Exception $e) {
            Log::instance()->add(Log::ERROR, 'set_column($a_columns = array()): ' . $e);
            Log::instance()->write();
            return false;
        }
    }

    /**
     *
     * @param <type> $column
     * @return <type>
     */
    public function query_all($column= array())
    {
        try {
            return $this->query_all_object($this, $column);
        } catch (Exception $e) {
            Log::instance()->add(Log::ERROR, 'query_all($column= array()): ' . $e);
            Log::instance()->write();
            return null;
        }
    }

    /**
     *
     * @param <type> $column
     * @return <type>
     */
    public function query($column= array())
    {
        try {
            return $this->query_object($this, $column);
        } catch (Exception $e) {
            Log::instance()->add(Log::ERROR, 'query($column= array()): ' . $e);
            Log::instance()->write();
            return null;
        }
    }

    /**
     *
     * @param <type> $offset
     * @param <type> $limit
     * @return <type>
     */
    public function load_all($offset, $limit,$filter, $sort,$count)
    {
        try {
            return $this->load_all_object($this, $offset, $limit,$filter, $sort,$count);
        } catch (Exception $e) {
            Log::instance()->add(Log::ERROR, 'load_all($offset, $limit): ' . $e);
            Log::instance()->write();
            return null;
        }
    }

    /**
     *
     * @return <type> 
     */
    public function get_count(){
        try{
            return $this->get_count_object($this);
        } catch (Exception $e) {
            Log::instance()->add(Log::ERROR, 'get_count(): ' . $e);
            Log::instance()->write();
            return null;
        }
    }

}

?>
